package com.dky.satell.scheduled;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dky.satell.entity.xml.FileSchema;
import com.dky.satell.entity.OfflineFile;
import com.dky.satell.service.OfflineFileService;
import com.dky.satell.util.ServiceUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @ClassName FileScan
 * @Description
 * @Author fangyuan
 * @Date 2021/5/31
 * @Version 1.0
 **/
@Slf4j
@Component
public class FileScan implements ApplicationRunner {

    /**
     * 文件自动扫描路径
     */
    @Value("${file.scanPath}")
    private String scanPath;

    /**
     * 文件上传路径
     */
    @Value("${file.uploadPath}")
    private String uploadPath;

    /**
     * 文件自动采集业务目录
     */
    @Value("${file.businessDirectory}")
    private String businessDirectory;

    @Value("${proxy.file.send}")
    private String proxyFileSend;


    @Autowired
    private OfflineFileService offlineFileService;

    /**
     * 初始化项目时同步每个业务目录的fileSchema.meta文件
     */
    @Override
    public void run(ApplicationArguments args) {
        String[] directoryList = businessDirectory.split(",");
        if(directoryList == null || directoryList.length == 0) {
            return;
        }
        File root = new File(uploadPath);
        String[] fileList = root.list();
        for(String directory : directoryList) {
            File schemaFile = new File(scanPath + directory + File.separator + "fileSchema.meta");
            String fakeDirectory = directory.replaceAll("/", "-");
            String uploadName = fakeDirectory + "_" + schemaFile.getName();
            if(schemaFile.exists() && !this.metaExist(uploadName, fileList)) {
                File proxyMeta = new File(uploadPath + System.currentTimeMillis() + "_" + uploadName);
                try {
                    FileUtils.copyFile(schemaFile, proxyMeta);
                    FileSchema fileSchema = ServiceUtil.analysisXml(proxyMeta);
                    ServiceUtil.sendToProxy(proxyMeta.getName(), proxyMeta.length(), fileSchema.getRegion(), proxyFileSend);
                } catch (IOException e) {
                    log.error("目录[{}]代理文件[{}]生成失败", directory, "fileSchema.meta");
                }
            }
        }
    }

    /**
     * 定时同步指定目录的文件夹和文件
     */
//    @Scheduled(cron = "*/10 * * * * ?")
    public void scheduled() {
        String[] directoryList = businessDirectory.split(",");
        if(directoryList == null || directoryList.length == 0) {
            return;
        }
        for(String directory : directoryList) {
            Set<String> fileSet = new HashSet<>();
            QueryWrapper<OfflineFile> wr = new QueryWrapper();
            wr.eq("source", 2);
            List<OfflineFile> offlineFileList = offlineFileService.list(wr);
            if(!CollectionUtils.isEmpty(offlineFileList)) {
                offlineFileList.stream().forEach(e -> fileSet.add(e.getFileName() + "_" + e.getFileDirectory()));
            }
            File schemaFile = new File(scanPath + directory + File.separator + "fileSchema.meta");
            File root = new File(scanPath + directory);
            List<String> pathList = new ArrayList<>();
            this.fileList(root, pathList);
            if(CollectionUtils.isEmpty(pathList)) {
                log.info("目录[{}]中不存在文件", scanPath + directory);
                return;
            }
            //轮循处理文件
            for(String path : pathList) {
                String fileName = ServiceUtil.getFileNameByPath(path);
                String fileDirectory = ServiceUtil.buildFileDirectory(scanPath, path);
                if(fileName.endsWith(".meta") || fileSet.contains(fileName + "_" + fileDirectory)) {
                    continue;
                }
                String proxyFileName = System.currentTimeMillis() + "_" + fileName;
                File mateFile = new File(ServiceUtil.buildMetaName(path));
                File proxyMateFile = new File(uploadPath + ServiceUtil.buildMetaName(proxyFileName));
                FileSchema fileSchema;
                if(mateFile.exists()) {
                    fileSchema = ServiceUtil.analysisXml(mateFile);
                    try {
                        FileUtils.copyFile(mateFile, proxyMateFile);
                    } catch (IOException e) {
                        log.error("代理文件[{}]生成失败", ServiceUtil.buildMetaName(fileName));
                    }
                } else {
                    fileSchema = ServiceUtil.analysisXml(schemaFile);
                }
                OfflineFile offlineFile = new OfflineFile();
                BeanUtils.copyProperties(fileSchema, offlineFile);
                offlineFile.setProxyFileName(proxyFileName);
                offlineFile.setFileDirectory(fileDirectory);
                offlineFile.setFileName(fileName);
                if(fileSchema.getFields() != null) {
                    offlineFile.setAttrs(JSONObject.toJSONString(fileSchema.getFields().getFields()));
                }
                if(!StringUtils.hasLength(offlineFile.getName())) {
                    offlineFile.setName(this.buildName(fileName));
                }
                offlineFileService.insert(new File(path), offlineFile, proxyMateFile);
            }
        }
    }

    public static void fileList(File file,List<String> path) {
        if (file.exists()) {
            if (file.isFile()) {
                if(!"fileSchema.meta".equals(file.getName())) {
                    path.add(file.getAbsolutePath());
                }
            } else {
                File[] list = file.listFiles();
                if (list.length == 0) {
                    log.error(file.getAbsolutePath() + "为空");
                } else {
                    for (int i = 0; i < list.length; i++) {
                        fileList(list[i], path);
                    }
                }
            }
        } else {
            log.error("文件不存在！");
        }
    }

    private String buildName(String fileName) {
        String[] nameSplit = fileName.split("\\.");
        if(nameSplit.length > 1) {
            return nameSplit[0];
        }
        return fileName;
    }

    private boolean metaExist(String metaName, String[] fileList) {
        if(fileList == null) {
            return false;
        }
        for(String fileName : fileList) {
            if(fileName.contains(metaName)) {
                return true;
            }
        }
        return false;
    }

}
